home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-07-28 | 14.6 KB | 598 lines | [TEXT/MPS ] |
- /*
- File: DataItem.cp
-
- Copyright: © 1991-1994 by Apple Computer, Inc.
- All rights reserved.
-
- Part of the AOCE Sample SMSAM Package. Consult the license
- which came with this software for your specific legal rights.
-
- */
-
-
-
- #ifndef __DATAITEM__
- #include "DataItem.h"
- #endif
-
- #ifndef __DEBUGASSERT__
- #include "DebugAssert.h"
- #endif
-
- #ifndef __DEBUGCONSTANTS__
- #include "DebugConstants.h"
- #endif
-
- #ifndef __STDIO__
- #include <stdio.h>
- #endif
-
- /***********************************|****************************************/
-
- #pragma segment DataItem
-
- /***********************************|****************************************/
-
-
- inline long Minimum ( long a, long b)
- {
- return ( a < b ) ? a : b;
- }
-
- /***********************************|****************************************/
-
- ADataItem::ADataItem ()
- {
- }
-
- /***********************************|****************************************/
-
- ADataItem::~ADataItem ()
- {
- }
-
- /***********************************|****************************************/
-
- short
- CompareDataItems ( const void* aa, unsigned long alen, const void* bb, unsigned long blen )
- {
- register short diff = 0;
- unsigned long c = alen < blen ? alen : blen;
- const char* a = (char*) aa;
- const char* b = (char*) bb;
-
- while ( c-- > 0 )
- {
- diff = *a++ - *b++;
-
- if ( diff != 0 )
- break;
- }
-
- if ( diff == 0 )
- diff = (short) ( (long) alen - (long) blen );
-
- return diff;
- }
-
- /***********************************|****************************************/
-
- ADataItem&
- ADataItem::operator = ( const ADataItem& that )
- {
- if ( this != &that )
- {
- ReadFrom ( that.GetPhysicalStart (), that.GetPhysicalLength (), that.GetDataType() );
- }
- else
- {
- ASSERT ( this != &that );
- }
-
- return *this;
- }
-
- #if 1
- /***********************************|****************************************/
-
- ADataItem& ADataItem::operator = ( const long l )
- {
- ReadFrom ( &l, sizeof(l), typeLongInteger );
- return *this;
- }
-
- /***********************************|****************************************/
-
- ADataItem& ADataItem::operator = ( const char* str)
- {
- unsigned long len = strlen(str) + 1;
- ReadFrom ( str, len, typeChar );
- return *this;
- }
-
- /***********************************|****************************************/
-
- ADataItem& ADataItem::operator = ( const StringPtr str )
- {
- ReadFrom ( &str[1], str[0], typeChar );
- return *this;
- }
-
- /***********************************|****************************************/
-
- ADataItem::operator long () const
- {
- if ((GetDataType() == typeInteger) ||
- (GetDataType() == typeLongInteger) ||
- (GetDataType() == typeShortInteger) ||
- (GetDataType() == typeSMInt) ||
- (GetDataType() == typeLongInteger))
- return * (long *) GetPhysicalStart();
- else if (GetDataType() == typeBoolean)
- return * (Boolean *) GetPhysicalStart();
- else if (GetDataType() == typeChar) {
- long l;
- sscanf ( (char*) GetPhysicalStart(), "%d", & l );
- return l;
- } else {
- ASSERT ( false );
- return 0;
- }
- }
-
- /***********************************|****************************************/
-
- ADataItem::operator Str255& () const
- { static Str255 str;
-
- str[0] = 0;
- if (GetDataType() == typeChar)
- {
- str[0] = (unsigned char) GetPhysicalLength();
- WriteTo ( &str[1], str[0] );
- } else if ((GetPhysicalLength() >= sizeof(long)) &&
- ((GetDataType() == typeInteger) ||
- (GetDataType() == typeLongInteger) ||
- (GetDataType() == typeShortInteger) ||
- (GetDataType() == typeSMInt) ||
- (GetDataType() == typeLongInteger)))
- {
- str[0] = (unsigned char) sprintf ( (char*) &str[1], "%d", * (long *) GetPhysicalStart());
- } else {
- ASSERT ( false );
- str [ 0 ] = 0;
- }
-
- return str;
- }
-
- #endif
-
- /***********************************|****************************************/
-
- unsigned long
- ADataItem::ReadFrom ( const void* source, unsigned long sourceLength, DescType dataType )
- {
- unsigned long newLength = SetPhysicalLength ( sourceLength );
- ASSERT ( newLength >= sourceLength );
- unsigned long copiedLength = Minimum ( newLength, sourceLength );
- BlockMove ( source, (void*) GetPhysicalStart (), copiedLength );
- SetDataType ( dataType );
- return copiedLength;
- }
-
- /***********************************|****************************************/
-
- unsigned long
- ADataItem::WriteTo ( void* dest, unsigned long destLength ) const
- {
- unsigned long desiredLength = GetPhysicalLength ();
- ASSERT ( destLength >= desiredLength );
- unsigned long copiedLength = Minimum ( destLength, desiredLength );
- BlockMove ( GetPhysicalStart (), dest, copiedLength );
- return copiedLength;
- }
-
- /***********************************|****************************************/
-
- Boolean
- ADataItem::operator == ( const ADataItem& that ) const
- {
- if (that.GetDataType() == GetDataType())
- return 0 == ::CompareDataItems ( GetPhysicalStart (), GetPhysicalLength (), that.GetPhysicalStart (), that.GetPhysicalLength () );
- else
- return false;
- }
-
- /***********************************|****************************************/
-
- void
- ADataItem::FillDataItem ( unsigned char c )
- {
- unsigned char* p = (unsigned char*) GetPhysicalStart ();
- unsigned long length = GetPhysicalLength ();
-
- while ( length-- > 0 )
- *p++ = c;
- }
-
- /***********************************|****************************************/
-
- #ifndef __FSTREAM__
- #include "FStream.h"
- #endif
-
- extern ostream& DumpHex (ostream& s, const void *p, unsigned long size);
-
- ostream&
- ADataItem::operator >> ( ostream& stream ) const
- {
- if ( chrisFlag.Flag ( kExtensiveBufferDescribe ) )
- {
- stream << "ADataItem @ " << (void*) this << "\n";
- DescType type = GetDataType();
- stream << "\tGetDataType(): "; stream.write ( (char*) &type, sizeof(type)); stream << "\n";
- stream << "\tGetPhysicalLength (): " << GetPhysicalLength () << "\n";
- stream << "\tGetPhysicalStart (): ";
- DumpHex ( stream, (char*) GetPhysicalStart (), GetPhysicalLength () );
- }
- else
- {
- switch ( GetDataType () )
- {
- case typeChar:
- stream << "'";
- stream.write ( (char*) GetPhysicalStart (), GetPhysicalLength () );
- stream << "'";
- break;
-
- case typeBoolean:
- if ( * (Boolean *) GetPhysicalStart () )
- stream << "true ";
- else
- stream << "false ";
- break;
-
- case typeInteger:
- stream << * ( long *) GetPhysicalStart ();
- break;
-
- case typeSMInt:
- stream << * ( short *) GetPhysicalStart ();
- break;
-
- case typeTrue:
- stream << "TRUE ";
- break;
-
- case typeFalse:
- stream << "FALSE ";
- break;
-
- default:
- stream << "dataType:"; OutputOSType ( stream, GetDataType () ); stream << " ";
- stream << GetPhysicalLength () << " bytes @ " << (void*) GetPhysicalStart () << '\n';
- break;
- }
- }
-
- return stream;
- }
-
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- CDataItem::CDataItem ():
- ADataItem (),
- fIsExternal ( false ),
- fDataType( typeWildCard )
- {
- SetPhysicalLength ( sizeof ( unsigned long ) );
- }
-
- /***********************************|****************************************/
-
- CDataItem::CDataItem ( unsigned long length, DescType dataType ):
- ADataItem (),
- fIsExternal ( false ),
- fDataType ( dataType )
- {
- SetPhysicalLength ( length );
- }
-
- /***********************************|****************************************/
-
- CDataItem::CDataItem ( const void* source, unsigned long sourceLength, DescType dataType ):
- ADataItem (),
- fIsExternal ( false ),
- fDataType ( dataType )
- {
- SetPhysicalLength ( sourceLength );
- BlockMove ( (Ptr) source, (Ptr) GetPhysicalStart (), GetPhysicalLength () );
- }
-
- /***********************************|****************************************/
-
- CDataItem::CDataItem ( const ADataItem& that ):
- ADataItem (),
- fIsExternal ( false )
- {
- SetDataType ( that.GetDataType() );
- SetPhysicalLength ( that.GetPhysicalLength () );
- BlockMove ( (Ptr) that.GetPhysicalStart (), (Ptr) GetPhysicalStart (), (Size) GetPhysicalLength () );
- }
-
- /***********************************|****************************************/
-
- CDataItem::CDataItem ( const CDataItem& that ):
- ADataItem (),
- fIsExternal ( false )
- {
- SetDataType ( that.GetDataType() );
- SetPhysicalLength ( that.GetPhysicalLength () );
- BlockMove ( (Ptr) that.GetPhysicalStart (),(Ptr) GetPhysicalStart (),( Size) GetPhysicalLength () );
- }
-
- /***********************************|****************************************/
-
- CDataItem&
- CDataItem::operator = ( const CDataItem& that )
- {
- if ( this != &that )
- {
- SetDataType ( that.GetDataType() );
- ReadFrom ( that.GetPhysicalStart (), that.GetPhysicalLength (), that.GetDataType() );
- }
- else
- {
- ASSERT ( this != &that );
- }
-
- return *this;
- }
-
- /***********************************|****************************************/
-
- CDataItem::~CDataItem ()
- {
- if ( fIsExternal )
- DeallocatePtr( (Ptr) fType.fExternal.fDataItem );
- }
-
- /***********************************|****************************************/
-
- unsigned long
- CDataItem::SetPhysicalLength ( unsigned long length )
- {
- if ( fIsExternal )
- DeallocatePtr( (Ptr) fType.fExternal.fDataItem );
-
- if ( length < 0 )
- {
- fIsExternal = false;
- fType.fInternal.fLength = 0;
- return fType.fInternal.fLength;
- }
- else if ( length > kDataItemMaxInternalLength )
- {
- fType.fExternal.fDataItem = FAILNewPtrClear ( length );
- if ( fType.fExternal.fDataItem )
- {
- fIsExternal = true;
- return fType.fExternal.fLength = length;
- }
- else
- {
- ASSERT(noErr == MemError ());
- fIsExternal = false;
- return fType.fInternal.fLength = kDataItemMaxInternalLength;
- }
- }
- else
- {
- fIsExternal = false;
- return fType.fInternal.fLength = length;
- return length;
- }
- }
-
- /***********************************|****************************************/
-
- ostream&
- CDataItem::operator >> ( ostream& s ) const
- {
- ADataItem::operator >> ( s );
-
- #if debug
- if ( chrisFlag.Flag ( kExtensiveBufferDescribe ) )
- {
- s << "\tfIsExternal: " << (short) fIsExternal << '\n';
-
- if ( fIsExternal )
- {
- s << "\tfLength: " << fType.fExternal.fLength << '\n';
- s << "\tfDataItem: " << fType.fExternal.fDataItem;
- }
- else
- {
- s << "\tfLength: " << (short) fType.fInternal.fLength;
- // s << "\tfDataItem: " << fType.fInternal.fDataItem;
- }
- }
- #endif
-
- return s;
- }
-
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- CPrefixDataItem::CPrefixDataItem ( DataItemPrefix prefix, unsigned long logicalLength ):
- ADataItem (),
- fDataItem ( logicalLength + prefix ),
- fSource ( nil ),
- fPrefix ( prefix ),
- fUpdate ( false )
- {
- UpdatePrefixWithLength ( 0 );
- }
-
- /***********************************|****************************************/
-
- CPrefixDataItem::CPrefixDataItem ( const ADataItem& source, DataItemPrefix prefix ):
- ADataItem (),
- fDataItem ( (const char*) source.GetPhysicalStart () - prefix, source.GetPhysicalLength () + prefix ),
- fSource ( (ADataItem*) &source ),
- fPrefix ( prefix ),
- fUpdate ( false )
- {
- UpdatePrefixWithLength ( source.GetPhysicalLength () );
- }
-
- /***********************************|****************************************/
-
- CPrefixDataItem::CPrefixDataItem ( ADataItem& source, Boolean update, DataItemPrefix prefix ):
- ADataItem (),
- fDataItem ( (const char*) source.GetPhysicalStart () - prefix, source.GetPhysicalLength () + prefix ),
- fSource ( &source ),
- fPrefix ( prefix ),
- fUpdate ( update )
- {
- UpdatePrefixWithLength ( source.GetPhysicalLength () );
- }
-
- /***********************************|****************************************/
-
- CPrefixDataItem::CPrefixDataItem ( const void* source, unsigned long length, DataItemPrefix prefix ):
- ADataItem (),
- fDataItem ( (char*) source - prefix, length + prefix ),
- fSource ( nil ),
- fPrefix ( prefix ),
- fUpdate ( false )
- {
- UpdatePrefixWithLength ( length );
- }
-
- /***********************************|****************************************/
-
- void
- CPrefixDataItem::UpdatePrefixWithLength ( unsigned long length )
- {
- void* start = (void*) fDataItem.GetPhysicalStart ();
-
- switch ( fPrefix )
- {
- case kByte:
- *(unsigned char*) start = (unsigned char) length;
- break;
-
- case kWord:
- *(unsigned short*) start = (unsigned short) length;
- break;
-
- case kLong:
- *(unsigned long*) start = (unsigned long) length;
- break;
- }
- }
-
- /***********************************|****************************************/
-
- unsigned long
- CPrefixDataItem::SetLogicalLength ( unsigned long requestedLogicalLength )
- {
- unsigned long requestedPhysicalLength = requestedLogicalLength + fPrefix;
- unsigned long actualPhysicalLength = fDataItem.GetPhysicalLength ();
-
- if ( actualPhysicalLength < requestedPhysicalLength )
- {
- actualPhysicalLength = fDataItem.SetPhysicalLength ( requestedPhysicalLength );
- ASSERT_RETURN_ZERO ( actualPhysicalLength >= requestedPhysicalLength );
- }
-
- unsigned long actualLogicalLength = actualPhysicalLength - fPrefix;
- UpdatePrefixWithLength ( actualLogicalLength );
- return actualLogicalLength;
- }
-
- /***********************************|****************************************/
-
- unsigned long
- CPrefixDataItem::GetLogicalLength () const
- {
- switch ( fPrefix )
- {
- case kByte: return *(unsigned char*) fDataItem.GetPhysicalStart ();
- case kWord: return *(unsigned short*) fDataItem.GetPhysicalStart ();
- case kLong: return *(unsigned long*) fDataItem.GetPhysicalStart ();
- };
- return 0; //in case of error
- }
-
- /***********************************|****************************************/
-
- CPrefixDataItem::~CPrefixDataItem ()
- {
- UpdateNow ();
- }
-
- /***********************************|****************************************/
-
- unsigned long
- CPrefixDataItem::UpdateNow ()
- {
- if ( fUpdate && fSource )
- return fSource->ReadFrom ( GetLogicalStart (), GetLogicalLength (), typeWildCard );
- else
- return 0;
- }
-
- /***********************************|****************************************/
-
- ostream&
- CPrefixDataItem::operator >> ( ostream& s ) const
- {
- ADataItem::operator >> ( s );
-
- #if debug
- if ( chrisFlag.Flag ( kExtensiveBufferDescribe ) )
- {
- // s << "\tfDataItem: " << fDataItem << '\n';
- s << "\tfSource: " << fSource << '\n';
- s << "\tfPrefix: " << (short) fPrefix << '\n';
- s << "\tfUpdate: " << (short) fUpdate;
- }
- #endif
-
- return s;
- }
-
- /***********************************|****************************************/
- /***********************************|****************************************/
-
- CWrapperDataItem::CWrapperDataItem ( void* source, unsigned long length , DescType dataType ):
- ADataItem (),
- fSource ( source ),
- fLength ( length ),
- fDataType ( dataType )
- {
- }
-
- /***********************************|****************************************/
-
- CWrapperDataItem::~CWrapperDataItem ()
- {
- }
-
- /***********************************|****************************************/
-
- unsigned long
- CWrapperDataItem::SetPhysicalLength ( unsigned long newLength )
- {
- ASSERT ( newLength == fLength);
-
- return fLength;
- }
-
- /***********************************|****************************************/
-